//! # 日志管理模块
//! 
//! 提供结构化日志记录和管理功能，支持多种输出目标和格式。
//! 集成观测性上下文，实现日志和追踪的关联。

use super::traits::{LogManager, LogLevel};
use super::context::ObservabilityContext;
use rustcloud_core::{ServiceResult, ServiceError};
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
use async_trait::async_trait;
use serde_json::Value;

/// 内存日志管理器
/// 
/// 将日志存储在内存中，主要用于测试和开发环境。
pub struct MemoryLogManager {
    /// 管理器名称
    name: String,
    
    /// 是否启用
    enabled: bool,
    
    /// 日志级别过滤器
    level_filter: LogLevel,
    
    /// 存储的日志条目
    logs: Arc<RwLock<Vec<LogEntry>>>,
    
    /// 配置
    config: LogManagerConfig,
}

/// 日志条目
#[derive(Debug, Clone)]
pub struct LogEntry {
    /// 时间戳（微秒）
    pub timestamp_us: u64,
    
    /// 日志级别
    pub level: LogLevel,
    
    /// 日志消息
    pub message: String,
    
    /// 追踪ID
    pub trace_id: Option<String>,
    
    /// Span ID
    pub span_id: Option<String>,
    
    /// 服务名称
    pub service_name: Option<String>,
    
    /// 操作名称
    pub operation_name: Option<String>,
    
    /// 结构化字段
    pub fields: HashMap<String, Value>,
    
    /// 标签
    pub labels: HashMap<String, String>,
}

/// 日志管理器配置
#[derive(Debug, Clone)]
pub struct LogManagerConfig {
    /// 最大存储的日志条目数量
    pub max_entries: usize,
    
    /// 自动导出间隔（毫秒）
    pub export_interval_ms: u64,
    
    /// 批处理大小
    pub batch_size: usize,
    
    /// 启用字段过滤
    pub enable_field_filtering: bool,
    
    /// 允许的字段列表
    pub allowed_fields: Vec<String>,
}

impl Default for LogManagerConfig {
    fn default() -> Self {
        Self {
            max_entries: 100000,
            export_interval_ms: 5000,
            batch_size: 1000,
            enable_field_filtering: false,
            allowed_fields: Vec::new(),
        }
    }
}

impl MemoryLogManager {
    /// 创建新的内存日志管理器
    /// 
    /// # 参数
    /// * `name` - 管理器名称
    /// * `config` - 管理器配置
    /// 
    /// # 返回值
    /// 新的内存日志管理器实例
    pub fn new(name: String, config: LogManagerConfig) -> Self {
        Self {
            name,
            enabled: true,
            level_filter: LogLevel::Trace, // 默认接受所有级别
            logs: Arc::new(RwLock::new(Vec::new())),
            config,
        }
    }

    /// 获取所有日志条目
    /// 
    /// # 返回值
    /// 所有存储的日志条目的副本
    pub async fn get_logs(&self) -> Vec<LogEntry> {
        self.logs.read().await.clone()
    }

    /// 根据级别获取日志条目
    /// 
    /// # 参数
    /// * `level` - 日志级别
    /// 
    /// # 返回值
    /// 指定级别的所有日志条目
    pub async fn get_logs_by_level(&self, level: LogLevel) -> Vec<LogEntry> {
        let logs = self.logs.read().await;
        logs.iter()
            .filter(|entry| entry.level == level)
            .cloned()
            .collect()
    }

    /// 根据追踪ID获取日志条目
    /// 
    /// # 参数
    /// * `trace_id` - 追踪ID
    /// 
    /// # 返回值
    /// 指定追踪ID的所有日志条目
    pub async fn get_logs_by_trace_id(&self, trace_id: &str) -> Vec<LogEntry> {
        let logs = self.logs.read().await;
        logs.iter()
            .filter(|entry| entry.trace_id.as_ref() == Some(&trace_id.to_string()))
            .cloned()
            .collect()
    }

    /// 清空所有日志
    pub async fn clear(&self) {
        let mut logs = self.logs.write().await;
        logs.clear();
    }

    /// 设置启用状态
    /// 
    /// # 参数
    /// * `enabled` - 是否启用
    pub fn set_enabled(&mut self, enabled: bool) {
        self.enabled = enabled;
    }

    /// 获取统计信息
    /// 
    /// # 返回值
    /// 日志管理器统计信息
    pub async fn get_stats(&self) -> LogManagerStats {
        let logs = self.logs.read().await;
        
        let mut stats = LogManagerStats {
            total_entries: logs.len(),
            trace_entries: 0,
            debug_entries: 0,
            info_entries: 0,
            warn_entries: 0,
            error_entries: 0,
        };
        
        for entry in logs.iter() {
            match entry.level {
                LogLevel::Trace => stats.trace_entries += 1,
                LogLevel::Debug => stats.debug_entries += 1,
                LogLevel::Info => stats.info_entries += 1,
                LogLevel::Warn => stats.warn_entries += 1,
                LogLevel::Error => stats.error_entries += 1,
            }
        }
        
        stats
    }

    /// 维护存储大小限制
    async fn maintain_storage_limits(&self) {
        let mut logs = self.logs.write().await;
        if logs.len() > self.config.max_entries {
            let excess = logs.len() - self.config.max_entries;
            logs.drain(0..excess);
            tracing::debug!("清理了 {} 个旧的日志条目", excess);
        }
    }

    /// 过滤字段
    fn filter_fields(&self, fields: &HashMap<String, Value>) -> HashMap<String, Value> {
        if !self.config.enable_field_filtering || self.config.allowed_fields.is_empty() {
            return fields.clone();
        }
        
        fields.iter()
            .filter(|(key, _)| self.config.allowed_fields.contains(key))
            .map(|(k, v)| (k.clone(), v.clone()))
            .collect()
    }

    /// 检查日志级别是否应该被记录
    fn should_log(&self, level: LogLevel) -> bool {
        level as u8 >= self.level_filter as u8
    }
}

#[async_trait]
impl LogManager for MemoryLogManager {
    async fn log(&self, level: LogLevel, message: &str, context: Option<&ObservabilityContext>) -> ServiceResult<()> {
        if !self.enabled || !self.should_log(level) {
            return Ok(());
        }

        let entry = LogEntry {
            timestamp_us: std::time::SystemTime::now()
                .duration_since(std::time::UNIX_EPOCH)
                .unwrap()
                .as_micros() as u64,
            level,
            message: message.to_string(),
            trace_id: context.map(|c| c.trace_id.clone()),
            span_id: context.map(|c| c.span_id.clone()),
            service_name: context.map(|c| c.service_name.clone()),
            operation_name: context.map(|c| c.operation_name.clone()),
            fields: HashMap::new(),
            labels: context.map(|c| c.labels.clone()).unwrap_or_default(),
        };

        {
            let mut logs = self.logs.write().await;
            logs.push(entry);
        }

        // 维护存储限制
        self.maintain_storage_limits().await;

        tracing::trace!("记录日志: {:?} - {}", level, message);
        Ok(())
    }

    async fn log_structured(&self, level: LogLevel, message: &str, fields: HashMap<String, Value>, context: Option<&ObservabilityContext>) -> ServiceResult<()> {
        if !self.enabled || !self.should_log(level) {
            return Ok(());
        }

        let filtered_fields = self.filter_fields(&fields);

        let entry = LogEntry {
            timestamp_us: std::time::SystemTime::now()
                .duration_since(std::time::UNIX_EPOCH)
                .unwrap()
                .as_micros() as u64,
            level,
            message: message.to_string(),
            trace_id: context.map(|c| c.trace_id.clone()),
            span_id: context.map(|c| c.span_id.clone()),
            service_name: context.map(|c| c.service_name.clone()),
            operation_name: context.map(|c| c.operation_name.clone()),
            fields: filtered_fields,
            labels: context.map(|c| c.labels.clone()).unwrap_or_default(),
        };

        {
            let mut logs = self.logs.write().await;
            logs.push(entry);
        }

        // 维护存储限制
        self.maintain_storage_limits().await;

        tracing::trace!("记录结构化日志: {:?} - {} (字段数: {})", level, message, fields.len());
        Ok(())
    }

    async fn export(&self) -> ServiceResult<()> {
        if !self.enabled {
            return Ok(());
        }

        let logs_count = self.logs.read().await.len();
        tracing::debug!("导出日志数据: {} 条目", logs_count);
        
        // 在实际实现中，这里会将数据发送到外部系统
        // 比如Elasticsearch、Fluentd等
        
        Ok(())
    }

    fn name(&self) -> &str {
        &self.name
    }

    fn is_enabled(&self) -> bool {
        self.enabled
    }

    fn set_level_filter(&mut self, level: LogLevel) {
        self.level_filter = level;
    }
}

/// 日志管理器统计信息
#[derive(Debug, Clone)]
pub struct LogManagerStats {
    /// 总日志条目数量
    pub total_entries: usize,
    
    /// Trace级别日志数量
    pub trace_entries: usize,
    
    /// Debug级别日志数量
    pub debug_entries: usize,
    
    /// Info级别日志数量
    pub info_entries: usize,
    
    /// Warn级别日志数量
    pub warn_entries: usize,
    
    /// Error级别日志数量
    pub error_entries: usize,
}

/// NoOp日志管理器
/// 
/// 不执行任何操作的日志管理器，用于禁用日志功能。
pub struct NoOpLogManager {
    name: String,
}

impl NoOpLogManager {
    /// 创建新的NoOp日志管理器
    /// 
    /// # 返回值
    /// 新的NoOp日志管理器实例
    pub fn new() -> Self {
        Self {
            name: "noop".to_string(),
        }
    }
}

impl Default for NoOpLogManager {
    fn default() -> Self {
        Self::new()
    }
}

#[async_trait]
impl LogManager for NoOpLogManager {
    async fn log(&self, _level: LogLevel, _message: &str, _context: Option<&ObservabilityContext>) -> ServiceResult<()> {
        Ok(())
    }

    async fn log_structured(&self, _level: LogLevel, _message: &str, _fields: HashMap<String, Value>, _context: Option<&ObservabilityContext>) -> ServiceResult<()> {
        Ok(())
    }

    async fn export(&self) -> ServiceResult<()> {
        Ok(())
    }

    fn name(&self) -> &str {
        &self.name
    }

    fn is_enabled(&self) -> bool {
        false
    }

    fn set_level_filter(&mut self, _level: LogLevel) {
        // NoOp implementation
    }
}

/// 组合日志管理器
/// 
/// 可以同时使用多个日志管理器，将日志发送到多个目标。
pub struct CompositeLogManager {
    name: String,
    managers: Vec<Arc<dyn LogManager>>,
}

impl CompositeLogManager {
    /// 创建新的组合日志管理器
    /// 
    /// # 参数
    /// * `name` - 管理器名称
    /// * `managers` - 子管理器列表
    /// 
    /// # 返回值
    /// 新的组合日志管理器实例
    pub fn new(name: String, managers: Vec<Arc<dyn LogManager>>) -> Self {
        Self {
            name,
            managers,
        }
    }

    /// 添加管理器
    /// 
    /// # 参数
    /// * `manager` - 要添加的管理器
    pub fn add_manager(&mut self, manager: Arc<dyn LogManager>) {
        self.managers.push(manager);
    }

    /// 获取管理器数量
    /// 
    /// # 返回值
    /// 子管理器的数量
    pub fn manager_count(&self) -> usize {
        self.managers.len()
    }
}

#[async_trait]
impl LogManager for CompositeLogManager {
    async fn log(&self, level: LogLevel, message: &str, context: Option<&ObservabilityContext>) -> ServiceResult<()> {
        for manager in &self.managers {
            if let Err(e) = manager.log(level, message, context).await {
                tracing::error!("日志管理器 {} 记录日志失败: {}", manager.name(), e);
            }
        }
        Ok(())
    }

    async fn log_structured(&self, level: LogLevel, message: &str, fields: HashMap<String, Value>, context: Option<&ObservabilityContext>) -> ServiceResult<()> {
        for manager in &self.managers {
            if let Err(e) = manager.log_structured(level, message, fields.clone(), context).await {
                tracing::error!("日志管理器 {} 记录结构化日志失败: {}", manager.name(), e);
            }
        }
        Ok(())
    }

    async fn export(&self) -> ServiceResult<()> {
        for manager in &self.managers {
            if let Err(e) = manager.export().await {
                tracing::error!("日志管理器 {} 导出失败: {}", manager.name(), e);
            }
        }
        Ok(())
    }

    fn name(&self) -> &str {
        &self.name
    }

    fn is_enabled(&self) -> bool {
        self.managers.iter().any(|m| m.is_enabled())
    }

    fn set_level_filter(&mut self, _level: LogLevel) {
        // 组合管理器不直接处理级别过滤
        // 应该在子管理器级别设置
    }
}

/// 格式化日志条目为JSON字符串
/// 
/// # 参数
/// * `entry` - 日志条目
/// 
/// # 返回值
/// 格式化后的JSON字符串
pub fn format_log_entry_as_json(entry: &LogEntry) -> Result<String, serde_json::Error> {
    serde_json::to_string(entry)
}

/// 格式化日志条目为人类可读的字符串
/// 
/// # 参数
/// * `entry` - 日志条目
/// 
/// # 返回值
/// 格式化后的字符串
pub fn format_log_entry_as_text(entry: &LogEntry) -> String {
    let timestamp = std::time::UNIX_EPOCH + std::time::Duration::from_micros(entry.timestamp_us);
    let datetime = chrono::DateTime::<chrono::Utc>::from(timestamp);
    
    let mut parts = vec![
        datetime.format("%Y-%m-%d %H:%M:%S%.3f").to_string(),
        format!("{:5}", format!("{:?}", entry.level)),
    ];
    
    if let Some(ref service) = entry.service_name {
        parts.push(format!("[{}]", service));
    }
    
    if let Some(ref trace_id) = entry.trace_id {
        parts.push(format!("trace:{}", &trace_id[..8])); // 显示前8位
    }
    
    parts.push(entry.message.clone());
    
    if !entry.fields.is_empty() {
        let fields_str = entry.fields.iter()
            .map(|(k, v)| format!("{}={}", k, v))
            .collect::<Vec<_>>()
            .join(" ");
        parts.push(format!("fields:{{{}}}", fields_str));
    }
    
    parts.join(" ")
}